﻿using System;
using System.Collections.Generic;
using System.Linq;
using Inovout.Data.Domain;
using NHibernate;
using NHibernate.Engine;
using NHibernate.Linq;
using NHibernate.Proxy;

namespace Inovout.Data.Repository
{
    /// <summary>
    /// BaseRepository
    /// </summary>
    /// <typeparam name="TModel">模型类型</typeparam>
    public class BaseRepository<TModel> : BaseRepository, IRepository, IRepository<TModel> where TModel : class
    {
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="model">模型对象实例</param>
        public virtual void Save(TModel model)
        {
            Session.Save(model);
            //Session.Flush();
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="model">模型对象实例</param>
        public virtual void SaveOrUpdate(TModel model)
        {
            Session.SaveOrUpdate(model);
            //Session.Flush();
        }


        /// <summary>
        /// 删除模型
        /// </summary>
        /// <param name="model">模型对象实例</param>
        public void Delete(TModel model)
        {
            Session.Delete(model);
            //Session.Flush();
        }
        /// <summary>
        /// 根据主键查询
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>模型对象实例</returns>
        public TModel FindById(object id)
        {
            return Session.Load<TModel>(id);
        }
        /// <summary>
        /// 查询所有的模型集合
        /// </summary>
        /// <returns>模型对象集合</returns>
        public IEnumerable<TModel> FindAll()
        {
            return this.Query().AsEnumerable();
        }

          /// <summary>
        /// 批量插入，Id生成必须为非数据库生成，如：Guid，Uuid
        /// </summary>
        /// <param name="models">模型对象集合</param>
        public void BulkInsert(IEnumerable<TModel> models)
        {
            if (models.Any())
            {
                using (var tx = this.StatelessSession.BeginTransaction())
                {
                    foreach (var model in models)
                    {
                        this.StatelessSession.Insert(model);
                    }
                    tx.Commit();
                }
            }
        }
        /// <summary>
        /// 批量插入，Id生成必须为非数据库生成，如：Guid，Uuid且不能使用乐观锁，如：Version,Timestamp
        /// </summary>
        /// <param name="models">模型对象集合</param>
        public void BulkUpdate(IEnumerable<TModel> models)
        {
            if (models.Any())
            {
                using (var tx = this.StatelessSession.BeginTransaction())
                {
                    foreach (var model in models)
                    {
                        this.StatelessSession.Update(model);
                    }
                    tx.Commit();
                }
            }
        }
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="models">模型对象集合</param>
        public void BulkDelete(IEnumerable<TModel> models)
        {
            if (models.Any())
            {
                using (var tx = this.StatelessSession.BeginTransaction())
                {
                    foreach (var model in models)
                    {
                        this.StatelessSession.Delete(model);
                    }
                    tx.Commit();
                }
            }
        }
        /// <summary>
        /// 基于NHibernate的IQueryable对象实例。有状态的Session。
        /// </summary>
        /// <returns>有状态IQueryable对象实例</returns>
        public IQueryable<TModel> Query()
        {
            return this.Session.Query<TModel>();
        }
        /// <summary>
        /// 基于NHibernate的IQueryable对象实例。无状态的Session。
        /// </summary>
        /// <returns>无状态的IQueryable对象实例</returns>
        public IQueryable<TModel> StatelessQuery()
        {
            return this.StatelessSession.Query<TModel>();
        }
        /// <summary>
        /// 基于NHibernate的IQueryable对象实例。有状态的Session。
        /// </summary>
        /// <param name="queryCriteria">查询规则对象实例</param>
        /// <returns>有状态的IQueryable对象实例</returns>
        public IQueryable<TModel> Query(QueryCriteria queryCriteria)
        {
            if (queryCriteria == null)
            {
                throw new ArgumentNullException("queryCriteria");
            }
            var query = Session.Query<TModel>();
            if (queryCriteria.Filters != null && queryCriteria.Filters.Count > 0)
            {
                query = query.Where(queryCriteria.Filters);
            }
            if (queryCriteria.Orders != null && queryCriteria.Orders.Count > 0)
            {
                query = query.Order(queryCriteria.Orders);
            }
            return query;
        }
        /// <summary>
        /// 基于NHibernate的IQueryable对象实例。有状态的Session。
        /// </summary>
        /// <param name="queryCriteria">查询规则对象实例</param>
        /// <returns>无状态IQueryable对象实例</returns>
        public IQueryable<TModel> StatelessQuery(QueryCriteria queryCriteria)
        {
            if (queryCriteria == null)
            {
                throw new ArgumentNullException("queryCriteria");
            }
            var query = this.StatelessSession.Query<TModel>();
            if (queryCriteria.Filters != null && queryCriteria.Filters.Count > 0)
            {
                query = query.Where(queryCriteria.Filters);
            }
            if (queryCriteria.Orders != null && queryCriteria.Orders.Count > 0)
            {
                query = query.Order(queryCriteria.Orders);
            }
            return query;
        }

        public IndexedDataObjectPagedSet<TModel> Search(string keyword, int pageIndex = 1, int pageSize = 10)
        {
            return new IndexedDataObjectPagedSet<TModel>(
                null,                    //Session.Search<TModel>(query, pageIndex, pageSize),
                    pageIndex,
                    pageSize
                );
        }
        /// <summary>
        /// 重新回棋模型，在多线程开发时使用，用于切换不同线程的Session对象实例
        /// </summary>
        /// <param name="model">模型对象实例</param>
        public void Load(TModel model)
        {
            INHibernateProxy modelProxy = model as INHibernateProxy;
            if (NHibernateUtil.IsInitialized(model) || modelProxy == null)
            {
                return;
            }
            modelProxy.HibernateLazyInitializer.SetSession((ISessionImplementor)this.Session);
            modelProxy.HibernateLazyInitializer.Initialize();
        }
        /// <summary>
        /// 通过主键查找模型
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>模型对象实例</returns>
        object IRepository.FindById(object id)
        {
            return this.FindById(id);
            //var result = Session.Get<TModel>(id);
            ////由持久状态变为胶管状态，主要为EntityModelBinder前端层使用。
            //Session.Evict(result);
            //return result;
        }


        /// <summary>
        /// 基于NHibernate的IQueryable对象实例。有状态的Session。
        /// </summary>
        /// <param name="queryCriteria">查询规则对象实例</param>
        /// <returns>有状态的IQueryable对象实例</returns>
        IQueryable IRepository.Query(QueryCriteria queryCriteria)
        {
            return this.Query(queryCriteria);
        }

        /// <summary>
        /// 基于NHibernate的IQueryable对象实例。有状态的Session。
        /// </summary>
        /// <param name="queryCriteria">查询规则对象实例</param>
        /// <returns>无状态IQueryable对象实例</returns>
        IQueryable IRepository.StatelessQuery(QueryCriteria queryCriteria)
        {
            return this.StatelessQuery(queryCriteria);
        }

    }
}
